/**
 * @Author: Sagan
 * @Date: 2020/09/16 16:57
 */
package validate

import (
	"gitee.com/big_meteor/godash/lang"
	"gitee.com/big_meteor/godash/validate/constant"
	"reflect"
	"strings"
)

func Check(v interface{}, rule string) (bool, error) {
	if "" == rule {
		return true, nil
	}

	if reflect.Invalid == lang.GetType(v) {
		return false, constant.ERROR_INVALID
	}

	slice := strings.Split(rule, constant.RuleSep)

	flag, err := isRequire(v, slice)
	if nil != err {
		return false, err
	}
	if false == flag {
		return true, nil
	}

	for i := 0; i < len(slice); i++ {
		key, value := parseRule(slice[i])
		flag, err := checkItem(v, key, value)

		if nil != err {
			return false, err
		}

		if false == flag {
			return false, nil
		}
	}

	return true, nil
}

// Deprecated: 请使用Check函数替代
func CheckMsg(v interface{}, rule []string, msg map[string]string) (bool, string, error) {
	if 1 > len(rule) {
		return true, "", nil
	}

	flag, err := isRequire(v, rule)
	if nil != err {
		return false, "", err
	}
	if false == flag {
		return true, "", nil
	}

	if reflect.Invalid == lang.GetType(v) {
		return false, "", constant.ERROR_INVALID
	}

	for i := 0; i < len(rule); i++ {
		key, value := parseRule(rule[i])
		flag, err := checkItem(v, key, value)
		if nil != err {
			return false, "", err
		}

		if false == flag {
			if message, has := msg[key]; has {
				return false, message, nil
			}

			return false, constant.ParseMessage(key, "value", value), nil
		}
	}

	return true, "", nil
}

// Deprecated: 请使用Check函数替代
func CheckMult(v map[string]interface{}, rule map[string][]string, msg map[string]string) (bool, string, error) {
	for field, slice := range rule {

		if nil == v[field] {
			return false, "", constant.ERROR_INVALID
		}

		flag, err := isRequire(v[field], slice)
		if nil != err {
			return false, "", err
		}
		if false == flag {
			continue
		}

		value := v[field]

		for i := 0; i < len(slice); i++ {
			rk, rv := parseRule(slice[i])

			flag, err := checkItem(value, rk, rv)

			if nil != err {
				return false, "", err
			}

			if flag {
				continue
			}

			if v, has := msg[field+"."+rk]; has {
				return false, v, nil
			}

			if v, has := msg[field]; has {
				return false, v, nil
			}

			return false, constant.ParseMessage(rk, field, rv), nil
		}
	}

	return true, "", nil
}
